Learning Outcomes
After completing this worksheet you will be able to:
- Create new Widget Blueprints
- Design UI using the Unreal Engine UMG Editor
- Connect a progress bar widget to a c++ variable
*Using Unreal Engine 4.22.3
The only files you will need to complete this tutorial are the health bar background and fill:
Warning
Because this tutorial uses the c++ template …
PART 1 - SETUP
Create Project
- Launch Unreal
- Select ‘New Project’ tab
- Select ‘C++’ on the secondary tab panel
- Then choose ‘First Person’ and name the project UI Demo.

Modify Player
- Open the character class header file in Visual Studio
- Add the code below at the bottom of the public section and just above the protected section

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Health")
float Health;
UFUNCTION(BlueprintPure, Category = "Health")
float GetHealth();
UFUNCTION(BlueprintPure, Category = "Health")
FText GetHealthIntText();
It should look like this:

Generate methods for Character .cpp
add the new methods to the .cpp using the quick actions shortcut:
- Right click on the method declaration
- Select ‘Quick Actions and refactorings…’
- Select Create definition of (see image below)

Populate Character .cpp
Open up the Character .cpp and in the BeginPlay method set the health
Health = 1000.0f;
It should look like this:

Popluate the get methods in Character .cpp
Now populate the auto generated methods: GetHealth and GetHealthIntText
float AUIDemoCharacter::GetHealth()
{
return Health / 1000;
}
FText AUIDemoCharacter::GetHealthIntText()
{
int32 HP = FMath::RoundHalfFromZero(Health / 100);
FString HPS = FString::FromInt(HP);
FString HealthHUD = HPS + FString(TEXT("%"));
FText HPText = FText::FromString(HealthHUD);
return HPText;
}
C++ DONE (for now)
- Lets get back into engine…
- Compile your project to make sure there are no mistakes

Folder Structure
- In the content browser, navigate to ‘Content’ -> ‘FirstPerson’
- Create a new folder called ‘UI’ by right clicking on the right panel and selecting: ‘New Folder’

Your folder structure should look like this:

Open the UMG UI Designer
- Double click on the new ‘Health_UI’ widget blueprint

UMG Hello world :)
- Drag a Text Widget from the palette on the right hand side onto the canvas in the middle
- Update the details so that they match below

Get this to display (C++)
Before we can start manipulating UI in c++ we need to add some resources to the projects build.cs
- In Visual Studio, open the file .build.cs
- Add the resource below to the ‘PublicDependancyModuleNames’ list:
"UMG", "Slate", "SlateCore"
It should now look like this:

Populate HUD .cpp file
- autogenerate the BeginPlay method the same as we did in step [TODO: NUMBER]
- Open the HUD .cpp file
- add UserWidgets to the includes at the top:
#include "Blueprint/UserWidget.h"
- Add the code below to the constructor of the HUD .cpp file
static ConstructorHelpers::FClassFinder<UUserWidget> HealthBarObj(TEXT("/Game/FirstPerson/UI/Health_UI"));
HUDWidgetClass = HealthBarObj.Class;
The constructor should now look like this:

Populate the BeginPlay Method
Now add this code below to the BeginPlay method
Super::BeginPlay();
if (HUDWidgetClass != nullptr) {
CurrentWidget = CreateWidget<UUserWidget>(GetWorld(), HUDWidgetClass);
if (CurrentWidget) {
CurrentWidget->AddToViewport();
}
}
The beginPlay method should now look like this:

Test the HUD
Compile and play your project. ‘Hello World’ should now be display, loud and proud for all to see!

Congratulations
- If you have made it this far then you deserve a break. Stand up, stretch, shake your limbs and have a walk.
- We will see you back here in 10mins :)
PART 2 - HEALTH BAR
Import the Graphics
Now we are going to create the health bar in the HUD.
- Navigate to the UI Folder: ‘Content’ -> ‘FirstPerson’ -> ‘UI’
- Click the import button and navigate to your health bar graphics.
- import both the fill and background of the health bar

Create Sprites
Convert the fill and background graphics to sprites
- Right click the image in the content browser
- Select ‘Sprite Actions’
- Select ‘Create Sprite’

Test the Progress bat
You should now be able to test the progress bar by adjusting the value of ‘percent’ in the progress panel.

Blueprint time
Next we need to bind the Health Variable from our Player class to the percentage of the health widget.
- Click the ‘Bind’ dropdown next to the ‘Percent’ property in the ‘progress’ panel
- Then select ‘Create Binding’

The Blueprint
Match your new blueprint to the image below.

TEST in game
To test that the binding works we can write a simple timer loop that modifies the Health variable incrementally. This is purely to test the functionality. If you were writing a proper game then you would probably have an external source apply damage to the player and this would modify the player’s health.
To test the binding, first open the player .cpp and add the code below to the public section
FTimerHandle IncrementHandle;
void incrementHealth();
Now open the player .cpp
- First add an import to the top of the file
#include "TimerManager.h"
- Then at the bottom of the ‘BeginPlay’ method add the timer call:
GetWorldTimerManager().SetTimer(IncrementHandle, this, &AUIDemoCharacter::incrementHealth, 0.1f, true, 0.2f);
- Now lets add the timer method:
void AUIDemoCharacter::incrementHealth()
{
UE_LOG(LogTemp, Warning, TEXT("HEALTH"));
Health += 10;
if (Health > 1000) Health = 0;
}
Compile the game and PLAY!
You should see the health bar scrolling up and then reseting.
LS0tCnRpdGxlOiAnQ09NUDI4MCBXZWVrIDExOiBXb3Jrc2hvcCcKYXV0aG9yOiAiQWxjd3luIFBhcmtlciIKZGF0ZTogImByIGZvcm1hdChTeXMudGltZSgpLCAnJWQgJUIsICVZJylgIgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIHRoZW1lOiByZWFkYWJsZQogICAgaGlnaGxpZ2h0OiB6ZW5idXJuCiAgICB0b2NfZGVwdGg6IDIKICAgIHRvYzogeWVzCiAgIyBiZWFtZXJfcHJlc2VudGF0aW9uOgogICMgICBpbmNsdWRlczoKICAjICAgICBpbl9oZWFkZXI6CiAgIyAgICAgLSBzZXNzaW9uaW5mby50ZXgKICAjICAgICAtIEZhbG1vdXRoR2FtZXNBY2FkZW15VGhlbWUvYmVhbWVydGhlbWVGYWxtb3V0aEdhbWVzQWNhZGVteS50ZXgKICAjICAga2VlcF90ZXg6IG5vCiAgIyAgIHNsaWRlX2xldmVsOiAyCiAgIyAgIHRvYzogbm8KLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0KbGlicmFyeShrbml0cikKa25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBGQUxTRSwgZmlnLmFsaWduPSJjZW50ZXIiKQpvcHRzX2tuaXQkZ2V0KCJybWFya2Rvd24ucGFuZG9jLnRvIikKaHRtbCA8LSBrbml0cjo6b3B0c19rbml0JGdldCgicm1hcmtkb3duLnBhbmRvYy50byIpID09ICJodG1sIgoKCmBgYAoKCmBgYHtyIHJlc3VsdHM9J2FzaXMnfQppZiAoIWh0bWwpIHsKICBjYXQoIlxcdGl0bGV7XFxzZXNzaW9ubnVtYmVyOiBBbiBJbnRyb2R1Y3Rpb24gdG8gSENJfSBcXHN1YnRpdGxle1xcbW9kdWxlY29kZTogXFxtb2R1bGV0aXRsZX0gXFxmcmFtZXtcXHRpdGxlcGFnZX0gIikKfQpgYGAKCiMjIFJlZ2lzdGVyIEF0dGVuZGFuY2UKIVtBdHRlbmRhbmNlIG1vbml0b3JpbmcgaXMgaW4gcGxhY2UuIEl0IGlzIHlvdXIgcmVzcG9uc2FiaWxpdHkgdG8gZW5zdXJlIHRoYXQgeW91IGhhdmUgc2lnbmVkIHlvdXJzZWxmIGluLl0oYXNzZXRzL3RhcGl0LnBuZykKCiMjIExlYXJuaW5nIE91dGNvbWVzIApBZnRlciBjb21wbGV0aW5nIHRoaXMgd29ya3NoZWV0IHlvdSB3aWxsIGJlIGFibGUgdG86CgotICoqQ3JlYXRlKiogbmV3IFdpZGdldCBCbHVlcHJpbnRzCi0gKipEZXNpZ24qKiBVSSB1c2luZyB0aGUgVW5yZWFsIEVuZ2luZSBVTUcgRWRpdG9yCi0gKipDb25uZWN0KiogYSBwcm9ncmVzcyBiYXIgd2lkZ2V0IHRvIGEgYysrIHZhcmlhYmxlICAKCipVc2luZyBVbnJlYWwgRW5naW5lIDQuMjIuMwoKVGhlIG9ubHkgZmlsZXMgeW91IHdpbGwgbmVlZCB0byBjb21wbGV0ZSB0aGlzIHR1dG9yaWFsIGFyZSB0aGUgaGVhbHRoIGJhciBiYWNrZ3JvdW5kIGFuZCBmaWxsOgoKIVtSaWdodCBjbGljayBhbmQgc2F2ZV0oYXNzZXRzL2JnX1Byb2dyZXNzQmFyX0RlZmVuc2UucG5nKQoKIVtSaWdodCBjbGljayBhbmQgc2F2ZV0oYXNzZXRzL1Byb2dyZXNzQmFyX0RlZmVuc2UucG5nKQoKIyMgV2FybmluZwoKQmVjYXVzZSB0aGlzIHR1dG9yaWFsIHVzZXMgdGhlIGMrKyB0ZW1wbGF0ZSAuLi4gCgojIFBBUlQgMSAtIFNFVFVQCgojIyBDcmVhdGUgUHJvamVjdAoKLSBMYXVuY2ggVW5yZWFsCi0gU2VsZWN0ICdOZXcgUHJvamVjdCcgdGFiCi0gU2VsZWN0ICdDKysnIG9uIHRoZSBzZWNvbmRhcnkgdGFiIHBhbmVsCi0gVGhlbiBjaG9vc2UgJ0ZpcnN0IFBlcnNvbicgYW5kIG5hbWUgdGhlIHByb2plY3QgVUkgRGVtby4gCgohW10oYXNzZXRzLzAxLWNyZWF0ZS5wbmcpCgojIyBNb2RpZnkgUGxheWVyCi0gT3BlbiB0aGUgY2hhcmFjdGVyIGNsYXNzIGhlYWRlciBmaWxlIGluIFZpc3VhbCBTdHVkaW8KLSBBZGQgdGhlIGNvZGUgYmVsb3cgYXQgdGhlIGJvdHRvbSBvZiB0aGUgcHVibGljIHNlY3Rpb24gYW5kIGp1c3QgYWJvdmUgdGhlIHByb3RlY3RlZCBzZWN0aW9uCgohW10oYXNzZXRzLzItcGxheWVyLnBuZykKCmBgYHtjKyt9ClVQUk9QRVJUWShFZGl0QW55d2hlcmUsIEJsdWVwcmludFJlYWRXcml0ZSwgQ2F0ZWdvcnkgPSAiSGVhbHRoIikKZmxvYXQgSGVhbHRoOwoKVUZVTkNUSU9OKEJsdWVwcmludFB1cmUsIENhdGVnb3J5ID0gIkhlYWx0aCIpCmZsb2F0IEdldEhlYWx0aCgpOwoJClVGVU5DVElPTihCbHVlcHJpbnRQdXJlLCBDYXRlZ29yeSA9ICJIZWFsdGgiKQpGVGV4dCBHZXRIZWFsdGhJbnRUZXh0KCk7CmBgYAoKIyMgSXQgc2hvdWxkIGxvb2sgbGlrZSB0aGlzOgoKIVtdKGFzc2V0cy8zLmNoYXJhY3RlcmgucG5nKQoKCiMjIEdlbmVyYXRlIG1ldGhvZHMgZm9yIENoYXJhY3RlciAuY3BwCgphZGQgdGhlIG5ldyBtZXRob2RzIHRvIHRoZSAuY3BwIHVzaW5nIHRoZSBxdWljayBhY3Rpb25zIHNob3J0Y3V0OiAKCi0gUmlnaHQgY2xpY2sgb24gdGhlIG1ldGhvZCBkZWNsYXJhdGlvbgotIFNlbGVjdCAnUXVpY2sgQWN0aW9ucyBhbmQgcmVmYWN0b3JpbmdzLi4uJwotIFNlbGVjdCBDcmVhdGUgZGVmaW5pdGlvbiBvZiA8bWV0aG9kPiAoc2VlIGltYWdlIGJlbG93KQoKIVtdKGFzc2V0cy80LWdlbmVyYXRlLnBuZykKCiMjIFBvcHVsYXRlIENoYXJhY3RlciAuY3BwIAoKT3BlbiB1cCB0aGUgQ2hhcmFjdGVyIC5jcHAgYW5kIGluIHRoZSBCZWdpblBsYXkgbWV0aG9kIHNldCB0aGUgaGVhbHRoCmBgYApIZWFsdGggPSAxMDAwLjBmOwpgYGAKCkl0IHNob3VsZCBsb29rIGxpa2UgdGhpczogCgohW10oYXNzZXRzLzUtc2V0aGVhbHRoLnBuZykKCiMjIFBvcGx1YXRlIHRoZSBnZXQgbWV0aG9kcyBpbiBDaGFyYWN0ZXIgLmNwcApOb3cgcG9wdWxhdGUgdGhlIGF1dG8gZ2VuZXJhdGVkIG1ldGhvZHM6IEdldEhlYWx0aCBhbmQgR2V0SGVhbHRoSW50VGV4dAoKYGBgCmZsb2F0IEFVSURlbW9DaGFyYWN0ZXI6OkdldEhlYWx0aCgpCnsKCXJldHVybiBIZWFsdGggLyAxMDAwOwp9CgpGVGV4dCBBVUlEZW1vQ2hhcmFjdGVyOjpHZXRIZWFsdGhJbnRUZXh0KCkKewoJaW50MzIgSFAgPSBGTWF0aDo6Um91bmRIYWxmRnJvbVplcm8oSGVhbHRoIC8gMTAwKTsKCUZTdHJpbmcgSFBTID0gRlN0cmluZzo6RnJvbUludChIUCk7CglGU3RyaW5nIEhlYWx0aEhVRCA9IEhQUyArIEZTdHJpbmcoVEVYVCgiJSIpKTsKCUZUZXh0IEhQVGV4dCA9IEZUZXh0OjpGcm9tU3RyaW5nKEhlYWx0aEhVRCk7CglyZXR1cm4gSFBUZXh0Owp9CmBgYAoKIyMgQysrIERPTkUgKGZvciBub3cpCgotIExldHMgZ2V0IGJhY2sgaW50byBlbmdpbmUuLi4KLSBDb21waWxlIHlvdXIgcHJvamVjdCB0byBtYWtlIHN1cmUgdGhlcmUgYXJlIG5vIG1pc3Rha2VzCgohW10oYXNzZXRzLzUuNS1jb21waWxlLnBuZykKCgojIyBGb2xkZXIgU3RydWN0dXJlCgotIEluIHRoZSBjb250ZW50IGJyb3dzZXIsIG5hdmlnYXRlIHRvICdDb250ZW50JyAtPiAnRmlyc3RQZXJzb24nCi0gQ3JlYXRlIGEgbmV3IGZvbGRlciBjYWxsZWQgJ1VJJyBieSByaWdodCBjbGlja2luZyBvbiB0aGUgcmlnaHQgcGFuZWwgYW5kIHNlbGVjdGluZzogJ05ldyBGb2xkZXInCgohW10oYXNzZXRzLzYtbmV3Zm9sZGVyLlBORykKCiMjIFlvdXIgZm9sZGVyIHN0cnVjdHVyZSBzaG91bGQgbG9vayBsaWtlIHRoaXM6IAoKIVtdKGFzc2V0cy83LWZvbGRlcnN0cnVjdHVyZS5wbmcpCgojIyBDcmVhdGUgYSBuZXcgJ1dpZGdldCBCbHVlcHJpbnQnCgotIE9wZW4gdGhlIG5ldyAnVUknIGZvbGRlcgotIFJpZ2h0IGNsaWNrIG9uIHRoZSBlbXB0eSBwYW5lbCBhbmQgc2VsZWN0ICdVc2VyIEludGVyZmFjZScgLT4gJ1dpZGdldCBCbHVlcHJpbnQnCi0gTmFtZSB0aGUgYmx1ZXByaW50ICdIZWFsdGhfVUknLiBUaXA6IHNwZWxsaW5nIGlzIGltcG9ydGFudCBhcyB3ZSB3aWxsIHJlZmVyIGJhY2sgdG8gdGhpcyBsYXRlciBpbiBvdXQgY29kZS4gCgohW10oYXNzZXRzLzgtbmV3d2lkZ2V0LnBuZykKCiMjIE9wZW4gdGhlIFVNRyBVSSBEZXNpZ25lcgotIERvdWJsZSBjbGljayBvbiB0aGUgbmV3ICdIZWFsdGhfVUknIHdpZGdldCBibHVlcHJpbnQKCiFbXShhc3NldHMvOS11bWcucG5nKQoKIyMgVU1HIEhlbGxvIHdvcmxkIDopIAoKLSBEcmFnIGEgVGV4dCBXaWRnZXQgZnJvbSB0aGUgcGFsZXR0ZSBvbiB0aGUgcmlnaHQgaGFuZCBzaWRlIG9udG8gdGhlIGNhbnZhcyBpbiB0aGUgbWlkZGxlCi0gVXBkYXRlIHRoZSBkZXRhaWxzIHNvIHRoYXQgdGhleSBtYXRjaCBiZWxvdwoKIVtdKGFzc2V0cy8xMC1oZWxsby5qcGcpCgojIyBHZXQgdGhpcyB0byBkaXNwbGF5IChDKyspCgpCZWZvcmUgd2UgY2FuIHN0YXJ0IG1hbmlwdWxhdGluZyBVSSBpbiBjKysgd2UgbmVlZCB0byBhZGQgc29tZSByZXNvdXJjZXMgdG8gdGhlIHByb2plY3RzIGJ1aWxkLmNzCgotIEluIFZpc3VhbCBTdHVkaW8sIG9wZW4gdGhlIGZpbGUgPHByb2plY3QtbmFtZT4uYnVpbGQuY3MKLSBBZGQgdGhlIHJlc291cmNlIGJlbG93IHRvIHRoZSAnUHVibGljRGVwZW5kYW5jeU1vZHVsZU5hbWVzJyBsaXN0OgoKYGBgICJVTUciLCAiU2xhdGUiLCAiU2xhdGVDb3JlIiBgYGAKCkl0IHNob3VsZCBub3cgbG9vayBsaWtlIHRoaXM6CgohW10oYXNzZXRzLzEwLjUtYnVpbGQucG5nKQoKIyMgRWRpdCBIVUQgaGVhZGVyIGZpbGUKCi0gT3BlbiB0aGUgSFVEIGNsYXNzIGluIFZpc3VhbCBTdHVkaW8gKHJlbWVtYmVyIHRoaXMgY291bGQgYmUgY2FsbGVkIHNvbWV0aGluZyBlbHNlIGRlcGVuZGluZyBvbiB3aGF0IHlvdSBjYWxsZWQgeW91ciBwcm9qZWN0KQoKIVtdKGFzc2V0cy8xMS1IVUQucG5nKQoKIyMgSFVEIGhlYWRlciBmaWxlCgpVcGRhdGUgdGhlIHB1YmxpYyBhbmQgcHJpdmF0ZSBzZWN0aW9ucyB0byBsb29rIGxpa2UgdGhpczogCgpgYGAKcHVibGljOiAKICBBVUlEZW1vSFVEKCk7CgkKCS8qKiBQcmltYXJ5IGRyYXcgY2FsbCBmb3IgdGhlIEhVRCAqLwoJdmlydHVhbCB2b2lkIERyYXdIVUQoKSBvdmVycmlkZTsKCXZpcnR1YWwgdm9pZCBCZWdpblBsYXkoKSBvdmVycmlkZTsgIC8vIG5ldwoKcHJpdmF0ZToKCS8qKiBDcm9zc2hhaXIgYXNzZXQgcG9pbnRlciAqLwoJY2xhc3MgVVRleHR1cmUyRCogQ3Jvc3NoYWlyVGV4OwoJCgkvLyBuZXcKCVVQUk9QRVJUWShFZGl0QW55d2hlcmUsIENhdGVnb3J5ID0gIkhlYWx0aCIpCglUU3ViY2xhc3NPZjxjbGFzcyBVVXNlcldpZGdldD4gSFVEV2lkZ2V0Q2xhc3M7CgkKCS8vIG5ldwoJVVBST1BFUlRZKEVkaXRBbnl3aGVyZSwgQ2F0ZWdvcnkgPSAiSGVhbHRoIikKCWNsYXNzIFVVc2VyV2lkZ2V0KiBDdXJyZW50V2lkZ2V0Owp9OwoKYGBgCgojIyBQb3B1bGF0ZSBIVUQgLmNwcCBmaWxlCgotIGF1dG9nZW5lcmF0ZSB0aGUgQmVnaW5QbGF5IG1ldGhvZCB0aGUgc2FtZSBhcyB3ZSBkaWQgaW4gc3RlcCBbVE9ETzogTlVNQkVSXQotIE9wZW4gdGhlIEhVRCAuY3BwIGZpbGUKLSBhZGQgVXNlcldpZGdldHMgdG8gdGhlIGluY2x1ZGVzIGF0IHRoZSB0b3A6IAoKYGBgICNpbmNsdWRlICJCbHVlcHJpbnQvVXNlcldpZGdldC5oIiBgYGAKCi0gQWRkIHRoZSBjb2RlIGJlbG93IHRvIHRoZSBjb25zdHJ1Y3RvciBvZiB0aGUgSFVEIC5jcHAgZmlsZQoKYGBgCiAgc3RhdGljIENvbnN0cnVjdG9ySGVscGVyczo6RkNsYXNzRmluZGVyPFVVc2VyV2lkZ2V0PiBIZWFsdGhCYXJPYmooVEVYVCgiL0dhbWUvRmlyc3RQZXJzb24vVUkvSGVhbHRoX1VJIikpOwoJSFVEV2lkZ2V0Q2xhc3MgPSBIZWFsdGhCYXJPYmouQ2xhc3M7CmBgYAoKIyMgVGhlIGNvbnN0cnVjdG9yIHNob3VsZCBub3cgbG9vayBsaWtlIHRoaXM6IAoKIVtdKGFzc2V0cy8xMi1jb25zdHJ1Y3Rvci5wbmcpCgojIyBQb3B1bGF0ZSB0aGUgQmVnaW5QbGF5IE1ldGhvZAoKTm93IGFkZCB0aGlzIGNvZGUgYmVsb3cgdG8gdGhlIEJlZ2luUGxheSBtZXRob2QKCmBgYAogIFN1cGVyOjpCZWdpblBsYXkoKTsKICAKCWlmIChIVURXaWRnZXRDbGFzcyAhPSBudWxscHRyKSB7CgkJQ3VycmVudFdpZGdldCA9IENyZWF0ZVdpZGdldDxVVXNlcldpZGdldD4oR2V0V29ybGQoKSwgSFVEV2lkZ2V0Q2xhc3MpOwoJCWlmIChDdXJyZW50V2lkZ2V0KSB7CgkJCUN1cnJlbnRXaWRnZXQtPkFkZFRvVmlld3BvcnQoKTsKCQl9Cgl9CmBgYAoKIyMgVGhlIGJlZ2luUGxheSBtZXRob2Qgc2hvdWxkIG5vdyBsb29rIGxpa2UgdGhpczoKCiFbXShhc3NldHMvMTMtYmVnaW5wbGF5LnBuZykKCgojIyBUZXN0IHRoZSBIVUQKCkNvbXBpbGUgYW5kIHBsYXkgeW91ciBwcm9qZWN0LiAnSGVsbG8gV29ybGQnIHNob3VsZCBub3cgYmUgZGlzcGxheSwgbG91ZCBhbmQgcHJvdWQgZm9yIGFsbCB0byBzZWUhIAoKIVtdKGFzc2V0cy8xNC1odWR0ZXN0LnBuZykKCiMjIENvbmdyYXR1bGF0aW9ucwoKLSBJZiB5b3UgaGF2ZSBtYWRlIGl0IHRoaXMgZmFyIHRoZW4geW91IGRlc2VydmUgYSBicmVhay4gU3RhbmQgdXAsIHN0cmV0Y2gsIHNoYWtlIHlvdXIgbGltYnMgYW5kIGhhdmUgYSB3YWxrLiAKLSBXZSB3aWxsIHNlZSB5b3UgYmFjayBoZXJlIGluIDEwbWlucyA6KQoKCiMgUEFSVCAyIC0gSEVBTFRIIEJBUgoKIyMgSW1wb3J0IHRoZSBHcmFwaGljcwoKTm93IHdlIGFyZSBnb2luZyB0byBjcmVhdGUgdGhlIGhlYWx0aCBiYXIgaW4gdGhlIEhVRC4KCi0gTmF2aWdhdGUgdG8gdGhlIFVJIEZvbGRlcjogJ0NvbnRlbnQnIC0+ICdGaXJzdFBlcnNvbicgLT4gJ1VJJwotIENsaWNrIHRoZSBpbXBvcnQgYnV0dG9uIGFuZCBuYXZpZ2F0ZSB0byB5b3VyIGhlYWx0aCBiYXIgZ3JhcGhpY3MuCi0gaW1wb3J0IGJvdGggdGhlIGZpbGwgYW5kIGJhY2tncm91bmQgb2YgdGhlIGhlYWx0aCBiYXIKCiFbXShhc3NldHMvMTUtaW1wb3J0LnBuZykKCiMjIENyZWF0ZSBTcHJpdGVzCgpDb252ZXJ0IHRoZSBmaWxsIGFuZCBiYWNrZ3JvdW5kIGdyYXBoaWNzIHRvIHNwcml0ZXMKCi0gUmlnaHQgY2xpY2sgdGhlIGltYWdlIGluIHRoZSBjb250ZW50IGJyb3dzZXIKLSBTZWxlY3QgJ1Nwcml0ZSBBY3Rpb25zJwotIFNlbGVjdCAnQ3JlYXRlIFNwcml0ZScgCgohW10oYXNzZXRzLzE2LXNwcml0ZS5wbmcpCgojIyBVcGRhdGUgSGVhbHRoX1VJIFdpZGdldCBCbHVlcHJpbnQKCi0gT3BlbiB0aGUgJ0hlYWx0aF9VSScgV2lkZ2V0IEJsdWVwcmludCBieSBkb3VibGUgY2xpY2tpbmcgaXQgaW4gdGhlIGNvbnRlbnQgYnJvd3NlcgotIE1vdmUgdGhlICdIZWxsbyBXb3JsZCcgVGV4dCB3aWRnZXQgdG8gdGhlIHRvcCByaWdodCBoYW5kIGNvcm5lci4oY2hhbmdlIHRoZSB0ZXh0IGlmIHlvdSBsaWtlKQotIERyYWcgYSAnUHJvZ3Jlc3MgQmFyJyB3aWRnZXQgZnJvbSB0aGUgcGFsZXR0ZSBvbiB0byB0aGUgY2FudmFzIGFuZCBwb3NpdGlvbiBpdCBvbiB0aGUgdG9wIGxlZnQgaGFuZCBjb3JuZXIuIAoKVGhlIGNhbnZhcyBzaG91bGQgbG9vayBsaWtlIHRoaXM6CgohW10oYXNzZXRzLzE3LWh1ZC11cGRhdGUucG5nKQoKIyMgU3R5bGUgUHJvZ3Jlc3MgV2lkZ2V0CgpXaXRoIHRoZSAnUHJvZ3Jlc3MgQmFyJyBzZWxlY3RlZCwgYWRkIHRoZSBmaWxsIGFuZCBiYWNrZ3JvdW5kIHNwcml0ZXMgaW4gdGhlIERldGFpbHMgLT4gU3R5bGUgcGFuZWwuCgpJdCBTaG91bGQgbG9vayBsaWtlIHRoaXM6IAoKIVtdKGFzc2V0cy8xOC1mYW5kYi5qcGcpCgojIyBUZXN0IHRoZSBQcm9ncmVzcyBiYXQKCllvdSBzaG91bGQgbm93IGJlIGFibGUgdG8gdGVzdCB0aGUgcHJvZ3Jlc3MgYmFyIGJ5IGFkanVzdGluZyB0aGUgdmFsdWUgb2YgJ3BlcmNlbnQnIGluIHRoZSBwcm9ncmVzcyBwYW5lbC4KCiFbXShhc3NldHMvMTktcHJvZ3Jlc3MtcGFuZWwuanBnKQoKCiMjIEJsdWVwcmludCB0aW1lCgpOZXh0IHdlIG5lZWQgdG8gYmluZCB0aGUgSGVhbHRoIFZhcmlhYmxlIGZyb20gb3VyIFBsYXllciBjbGFzcyB0byB0aGUgcGVyY2VudGFnZSBvZiB0aGUgaGVhbHRoIHdpZGdldC4KCi0gQ2xpY2sgdGhlICdCaW5kJyBkcm9wZG93biBuZXh0IHRvIHRoZSAnUGVyY2VudCcgcHJvcGVydHkgaW4gdGhlICdwcm9ncmVzcycgcGFuZWwKLSBUaGVuIHNlbGVjdCAnQ3JlYXRlIEJpbmRpbmcnCgohW10oYXNzZXRzLzIwLWJpbmQucG5nKQoKIyMgVGhlIEJsdWVwcmludAoKTWF0Y2ggeW91ciBuZXcgYmx1ZXByaW50IHRvIHRoZSBpbWFnZSBiZWxvdy4gCgohW10oYXNzZXRzLzIxLWJsdWVwcmludC5wbmcpCgoKIyMgVEVTVCBpbiBnYW1lClRvIHRlc3QgdGhhdCB0aGUgYmluZGluZyB3b3JrcyB3ZSBjYW4gd3JpdGUgYSBzaW1wbGUgdGltZXIgbG9vcCB0aGF0IG1vZGlmaWVzIHRoZSBIZWFsdGggdmFyaWFibGUgaW5jcmVtZW50YWxseS4gVGhpcyBpcyBwdXJlbHkgdG8gdGVzdCB0aGUgZnVuY3Rpb25hbGl0eS4gSWYgeW91IHdlcmUgd3JpdGluZyBhIHByb3BlciBnYW1lIHRoZW4geW91IHdvdWxkIHByb2JhYmx5IGhhdmUgYW4gZXh0ZXJuYWwgc291cmNlIGFwcGx5IGRhbWFnZSB0byB0aGUgcGxheWVyIGFuZCB0aGlzIHdvdWxkIG1vZGlmeSB0aGUgcGxheWVyJ3MgaGVhbHRoLiAKClRvIHRlc3QgdGhlIGJpbmRpbmcsIGZpcnN0IG9wZW4gdGhlIHBsYXllciAuY3BwIGFuZCBhZGQgdGhlIGNvZGUgYmVsb3cgdG8gdGhlIHB1YmxpYyBzZWN0aW9uCgpgYGAKRlRpbWVySGFuZGxlIEluY3JlbWVudEhhbmRsZTsgCnZvaWQgaW5jcmVtZW50SGVhbHRoKCk7CmBgYAoKTm93IG9wZW4gdGhlIHBsYXllciAuY3BwCgotIEZpcnN0IGFkZCBhbiBpbXBvcnQgdG8gdGhlIHRvcCBvZiB0aGUgZmlsZQpgYGAKI2luY2x1ZGUgIlRpbWVyTWFuYWdlci5oIgpgYGAKCi0gVGhlbiBhdCB0aGUgYm90dG9tIG9mIHRoZSAnQmVnaW5QbGF5JyBtZXRob2QgYWRkIHRoZSB0aW1lciBjYWxsOiAKYGBgCkdldFdvcmxkVGltZXJNYW5hZ2VyKCkuU2V0VGltZXIoSW5jcmVtZW50SGFuZGxlLCB0aGlzLCAmQVVJRGVtb0NoYXJhY3Rlcjo6aW5jcmVtZW50SGVhbHRoLCAwLjFmLCB0cnVlLCAwLjJmKTsKYGBgCgotIE5vdyBsZXRzIGFkZCB0aGUgdGltZXIgbWV0aG9kOiAKYGBgCnZvaWQgQVVJRGVtb0NoYXJhY3Rlcjo6aW5jcmVtZW50SGVhbHRoKCkKewoJVUVfTE9HKExvZ1RlbXAsIFdhcm5pbmcsIFRFWFQoIkhFQUxUSCIpKTsKCUhlYWx0aCArPSAxMDsKCWlmIChIZWFsdGggPiAxMDAwKSBIZWFsdGggPSAwOwp9CmBgYAoKQ29tcGlsZSB0aGUgZ2FtZSBhbmQgUExBWSEKCllvdSBzaG91bGQgc2VlIHRoZSBoZWFsdGggYmFyIHNjcm9sbGluZyB1cCBhbmQgdGhlbiByZXNldGluZy4gCgojIyBGVVJUSEVSIFJFU09VUkNFUwoKLQotCi0KCgoKCgoKCgoKCgoKCgo=